/*
 * @Author: Grant
 * @Date: 2020-12-26 20:37:09
 * @LastEditTime: 2020-12-27 15:38:21
 * @LastEditors: Grant
 * @FilePath: \nest-crud-basic\src\users\users.controller.ts
 */
import {
  HttpStatus,
  Controller,
  Get,
  HttpException,
  Post,
  Body,
  NotAcceptableException,
  Delete,
  Param,
  ServiceUnavailableException,
  Put,
} from '@nestjs/common';
import { UserDTO } from './userDto';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { InjectModel } from 'nestjs-typegoose';
import { User } from './users.model';
import { ReturnModelType } from '@typegoose/typegoose';

@ApiTags(`users crud`)
@Controller('users')
export class UsersController {
  constructor(
    @InjectModel(User) private readonly UserModel: ReturnModelType<typeof User>,
  ) {}
  @Get()
  @ApiOperation({ summary: `find all users` })
  async showAllUsers(): Promise<UserDTO[]> {
    try {
      return await this.UserModel.find();
    } catch (error) {
      throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
    }
  }

  @Post()
  @ApiOperation({ summary: `create one new user` })
  async create(@Body() newUser: UserDTO): Promise<string> {
    try {
      await this.UserModel.create(newUser);
      return `Create Success!!!`;
    } catch (error) {
      throw new NotAcceptableException();
    }
  }

  @Delete(`:id`)
  @ApiOperation({ summary: `delete one new user` })
  async removeUser(@Param(`id`) userId: string): Promise<string> {
    try {
      await this.UserModel.findByIdAndDelete(userId);
      return userId;
    } catch (error) {
      throw new ServiceUnavailableException();
    }
  }

  @Put(`:id`)
  @ApiOperation({ summary: `update one new user` })
  async updateUser(
    @Param(`id`) userId: string,
    @Body() updateBody: UserDTO,
  ): Promise<UserDTO> {
    try {
      await this.UserModel.findByIdAndUpdate(userId, updateBody);
      return updateBody;
    } catch (error) {
      throw new HttpException(`update fail`, 403);
    }
  }

  @Get(`:id`)
  @ApiOperation({ summary: `find one new user` })
  async findOneUser(@Param(`id`) userId: string): Promise<UserDTO> {
    try {
      return await this.UserModel.findById(userId);
    } catch (error) {
      throw new HttpException(`can't find`, 404);
    }
  }
}
